package NFHE_Function

/*
    #cgo CFLAGS: -I../
    #cgo LDFLAGS: -L../ -ldecd -lm
	#include "compute.h"
	#include "device.h"
	#include "key.h"
	#include "manager.h"
	#include "xdma.h"
    #include <stdlib.h>
*/
import "C"
import (
	"errors"
	"fmt"
	"unsafe"
)

func NFHE_ENC(plainData uint) ([]byte, error) {
	var err error         // 出错返回值
	var Ret_Result []byte // 功能返回值
	plainData1 := C.uint(plainData)
	bt := make([]byte, 128)                   // 初始化256个字节
	encData := GetBytePointer(bt)             // 将cgo的字节转换为c语言的字节类型
	rv := C.NFHE_Encrypt(plainData1, encData) // 对明文加密
	if rv != 0 {
		cw := fmt.Sprintf("%x", rv)
		err = errors.New("出错信息:同态加密时出错！错误号：" + cw)
	} else {
		Ret_Result = bt[0:128] //hex.EncodeToString(bt)
		//Ret_Result = C.GoStringN(encData, 256) // 取出加密值
		//fmt.Println(Ret_Result)
	}
	return Ret_Result, err
}

func NFHE_DEC(encData []byte) (uint, error) {
	var err error          // 出错返回值
	var ret_plainData uint // 功能返回值
	//encData1, _ := hex.DecodeString(encData)
	//encDataTmp := GetBytePointerStr(encData1)
	encData_str := GetBytePointer(encData) // 将go字符串转换C字符串
	//defer C.free(unsafe.Pointer(encData_str)) // 动态回收内存空间
	//var encData_str1 = (*C.uchar)(unsafe.Pointer(encData_str)) // 将C字符串转换C.char指针
	var ncount uint
	//bt1 := make([]byte, ncount)                   // 给解密结果赋初值
	PainData := (*C.uint)(unsafe.Pointer(&ncount)) // 将cgo的字节转换为c语言的uint类型
	rv := C.NFHE_Decrypt(encData_str, PainData)    // 解密
	if rv != 0 {
		cw := fmt.Sprintf("%x", rv)
		err = errors.New("出错信息:同态解密时出错！错误号：" + cw)
		fmt.Println(err)
	} else {
		ret_plainData = uint(*PainData)
		return ret_plainData, err
	}
	return ret_plainData, err
}

// 将cgo的字节转换为c语言uchar
func GetBytePointer(val []byte) *C.uchar {
	return (*C.uchar)(unsafe.Pointer(&val[0]))
}

// 将cgo的字节转换为c语言uchar
func GetBytePointerStr(val []byte) *C.char {
	return (*C.char)(unsafe.Pointer(&val[0]))
}

// 将cgo的uint转换为c语言uint32
func GetUintPointeruint32(val []byte) *C.uint {
	return (*C.uint)(unsafe.Pointer(&val[0]))
}
